# 本脚本用于生成线损分析树的json文件，以及生成给storm平台运算的csv数据文件，以及根据storm平台运算结果生成对应的线损结果json数据文件。
# 本脚本文件需要四个命令行参数：
# 1、生成json数据文件地址，如：hadoop/apache/htdocs/websiteLineloss/data.json
# 2、生成给storm使用的数据文件，如：hadoop/apache/htdocs/websiteLineloss/data.csv
# 3、storm的线损分析结果目录路径，如：hadoop/apache/htdocs/websiteLineloss/datatesting.csv/
# 4、根据storm结果汇总的json文件，用于前端网页显示，如：hadoop/apache/htdocs/websiteLineloss/data3.json
# -*- coding: utf-8 -*-
import random
import string
import json
import sys
import csv
import time
import os
from os.path import join, getsize
level=0
list={}
# 把一个子节点添加到item节点上
def addAChildToitem(item):
	if item.has_key('children'):
		item['children'].append(createAnEndNode())
	else:
		item['children']=[]
		item['children'].append(createAnEndNode())
	return item
# 添加一个最下层的叶子节点
def createAnEndNode():
	global total
	global level
	total+=1	
	return {	
		'name':str(++total),'level':level
	}
# 给node节点添加一个随机输入输出电量（根据父节点的输出决定）
def createRandomInOut(node,parent):
	if parent==None:#说明这是根节点
		inVol=random.uniform(100000, 1000000)
		outVol=random.uniform(100000,1000000)
		while outVol>=inVol:
			outVol=random.uniform(100000,1000000)
		node['in']=str(inVol)
		node['out']=str(outVol)
		for child in node['children']:
			createRandomInOut(child,node)
	else:		
		if node.has_key('children'):
			node['in']=float(parent['out'])/len(parent['children'])
			if random.randint(0,2)==1:
				node['in']=node['in']*0.99999
			else:
				node['in']=node['in']
			#print float(parent['out'])/len(parent['children']),node['in']
			node['out']=node['in']
			node['in']=str(node['in'])
			node['out']=str(node['out'])
			for child in node['children']:
				createRandomInOut(child,node)
		else:#端点，使用的是电表类型，电表类型没有输入，只有输出售电量
			node['out']=float(parent['out'])/len(parent['children'])*0.85
			node['out']=str(node['out'])
			node['in']='0'
			return
total=0
# 得到node节点的所有子节点名字，返回一个由空格隔开的字符串
def getAllChildrenName(node):
	result=''
	if node.has_key('children'):
		for item in node['children']:
			result+=item['name']+' '
	else:
		return ''
	return result
# 得到所有子节点的输入之和
def getAllChildrenIn(node):
	result=''
	if node.has_key('children'):
		for item in node['children']:			
			if item.has_key('children'):		
				result+=item['in']+' '	
			else:
				result+=item['out']+' '		
	else:
		return ''
	return result
def addRootToCsv(data,f):
	total=0
	#生成标题行
	f.writerow(['name', 
		'totalnodelengthforroot','level', 
		'children','in','out'])	
	f.writerow([data['name'], 
		data['totalnodelength'], 
		data['level'],
		#getAllChildrenName(data),data['in'],data['out']])
		getAllChildrenIn(data),data['in'],data['out']])
	for item in data['children']:
		addNodeToCsv(item,f)
def addNodeToCsv(node,f):
	global total
	total+=1
	if node.has_key('in') and node['in']!="0":
		f.writerow([node['name'], 
			'', 
			node['level'],
			getAllChildrenIn(node),node['in'],node['out']])
	if node.has_key('children'):			
		for item in node['children']:
			addNodeToCsv(item,f)
	else:
		return	
#遍历dir路径下的文件 
def getdirsize(dir): 
	for root, dirs, files in os.walk(dir):
		for name in files:			
			if name.find('lineloss-m')==0:
				readACsv(join(root, name))
# 读取一个csv文件并生成json
def readACsv(filePath):
	f=open(filePath,'rb')
	reader=csv.reader(f)
	i=0
	for line in reader:
		i+=1
		openTheJsonWithLine(line[0])
	f.close()
def openTheJsonWithLine(line):
	words=line.split('\t')
	list.setdefault(words[0],words[1])
if __name__ == '__main__':
	while True:
		data={'name':'0','level':level}
		level=0
		total=0
		level+=1
		for i in xrange(0,random.randint(17,20)):
			addAChildToitem(data)
		level+=1
		for j in xrange(0,len(data['children'])):
			for i in xrange(1,random.randint(17,20)):
				addAChildToitem(data['children'][j])
		level+=1
		for j in xrange(0,len(data['children'])):
			for i in xrange(0,len(data['children'][j]['children'])):
				for z in xrange(1,random.randint(17,20)):
					addAChildToitem(data['children'][j]['children'][i])
		level+=1
		for j in xrange(0,len(data['children'])):
			for i in xrange(0,len(data['children'][j]['children'])):
				for z in xrange(0,len(data['children'][j]['children'][i]['children'])):
					for k in xrange(1,random.randint(15,17)):
						addAChildToitem(data['children'][j]['children'][i]['children'][z])	
		createRandomInOut(data,None)
		data['totalnodelength']=total		
		if len(sys.argv)==5:
			#argv[1]是生成的json文件地址，
			#argv[2]是生成的csv文件地址
			#argv[3]是线损分析结果存放的目录
			#argv[4]是生成的线损分析json文件地址
			file=open(sys.argv[1],'w')
			file.write(json.dumps(data,sort_keys=True))
			file.close()
			print "生成json节点数："+str(total)
			total=0
			file=open(sys.argv[2],'wb+')
			f=csv.writer(file)			
			addRootToCsv(data,f)
			file.close()
			print "生成csv节点数："+str(total)
			time.sleep(10)
			print "把线损分析结果汇总到json"
			folder=sys.argv[3]
			list={}
			filesize = getdirsize(folder)
			file=open(sys.argv[4],'w')
			file.write(json.dumps(list,sort_keys=True))
			file.close() 
		else:
			file=open('data.json','w')
			file.write(json.dumps(data,sort_keys=True))
			file.close()
			print "生成json节点数："+str(total)
			total=0
			file=open('data.csv','wb+')
			f=csv.writer(file)
			addRootToCsv(data,f)
			file.close()
			print "生成csv节点数："+str(total)	
			time.sleep(10)
			print "把线损分析结果汇总到json"
			folder='F:/finaldesign/gitoschina/project d3/datatesting.csv'
			list={}
			filesize = getdirsize(folder)
			file=open('data3.json','w')
			file.write(json.dumps(list,sort_keys=True))
			file.close() 
		